package com.quanyou.sdk;

import org.slf4j.Logger;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by lishaoyan on 2015/6/19.
 *
 * log helper is to log the core log to dedicated destination
 *
 * The log output format is like:
 *  timestamp, hostname, module ("updown", "xxx"), unique-session-id, metric, logs (a json string)
 *
 *  metric format suggestion: WITH01, BCV01, BCK02
 */
public class AuditLogHelper {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(AuditLogHelper.class);

    private static AtomicLong logseq = new AtomicLong(0);

    // hostname
    private static String hostname = "unknown";

    // appid
    private static String appId = "zzexample";

    // id prefix
    private static String idprefix = String.format("%s-%x-", appId, System.currentTimeMillis()
            - 45L * 365 * 24 * 3600 * 1000);

    // module name
    private String moduleName;

    // session id
    private String sessionUniqId = null;

    static {
        try {
            hostname = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    /**
     *  log the information with the specified metric
     * @param metric  the log's metric id. Its format is like 'WITH01', 'BCV01', etc.
     * @param logs the log's contents. It MUST a json string.
     */
    public void log(String metric, String logs) {
        if (metric == null || logs == null) {
            return;
        }

        StringBuffer sb = new StringBuffer("{");
        sb.append(String.format("\"m_name\": \"%s\", ", metric));
        sb.append(String.format("\"m_host\": \"%s\", ", hostname));
        sb.append(String.format("\"m_time\": %.3f, ", System.currentTimeMillis() / 1000.0));
        sb.append(String.format("\"m_appid\": \"%s\", ", appId));
        sb.append(String.format("\"m_module\": \"%s\", ", moduleName));
        sb.append(String.format("\"m_id\": \"%s\", ", sessionUniqId != null ? sessionUniqId : getUniqId()));
        if (logs.startsWith("{")) {
            // "{}"
            if (logs.substring(1).trim().equals("}")) {
                sb.append("\"value\": \"{}\"}");
            } else {
                sb.append(logs.substring(1));
            }
        } else if (logs.startsWith("[")) {
            sb.append("\"value\": ");
            sb.append(logs).append("}");
        } else {
            sb.append(String.format("\"value\": \"%s\"}", logs.replace("\"", "'")));
        }

        logger.info("{}", sb.toString());
    }

    /**
     *  getSimpleRegionModel the logger instance whose log items use the different session id
     * @param moduleName the module name of log
     * @return a logger instance
     */
    public static AuditLogHelper getLogger(String moduleName) {
        return new AuditLogHelper(moduleName);
    }

    /**
     * getSimpleRegionModel the logger instance whose log items use the same session id
     * @param moduleName the name of module
     * @return a session logger instance
     */
    public static AuditLogHelper getSessionLogger(String moduleName) {
        return new AuditLogHelper(moduleName, "session");
    }

    private AuditLogHelper(String module) {
        moduleName = module;
        sessionUniqId = null;
    }

    private AuditLogHelper(String module, String xx) {
        moduleName = module;
        sessionUniqId = getUniqId();
    }

    private String getUniqId() {
        return idprefix + logseq.getAndIncrement();
    }
}

